package com.easylinkin.linkappapi.space.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.easylinkin.linkappapi.annotation.CommonOperateLogAnnotate;
import com.easylinkin.linkappapi.asset.entity.Asset;
import com.easylinkin.linkappapi.asset.service.AssetService;
import com.easylinkin.linkappapi.common.constant.CommonConstant;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.entity.DeviceRefAreaScope;
import com.easylinkin.linkappapi.device.entity.DeviceVoExt;
import com.easylinkin.linkappapi.device.service.DeviceRefAreaScopeService;
import com.easylinkin.linkappapi.device.service.DeviceService;
import com.easylinkin.linkappapi.function.entity.TenantFunctionRefArea;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogModule;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.space.entity.LinkappArea;
import com.easylinkin.linkappapi.space.entity.LinkappSpace;
import com.easylinkin.linkappapi.space.service.LinkappAreaService;
import com.easylinkin.linkappapi.space.vo.SpaceTreeVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author liuming
 * @since 2020-04-14
 */

@RestController
@RequestMapping("/area")
@Api(value="区域控制器",tags={"区域"})
public class LinkappAreaController {

    @Autowired
    LinkappAreaService linkappAreaService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    AssetService assetService;
    @Lazy
    @Resource
    DeviceRefAreaScopeService deviceRefAreaScopeService;
    @Resource
    LinkappUserContextProducer linkappUserContextProducer;

    @PostMapping("/addLinkappArea")
    @ApiOperation("新增区域")
    @CommonOperateLogAnnotate(module = LogModule.AREA, desc = "新增区域")
    public RestMessage addLinkappArea(@RequestBody LinkappArea linkappArea) {
        LinkappArea linkappAreaQuery = new LinkappArea();
        linkappAreaQuery.setAreaName(linkappArea.getAreaName());
        linkappAreaQuery.setParentId(linkappArea.getParentId());
        List<LinkappArea> listQuery = linkappAreaService.selectLinkappAreaList(linkappAreaQuery);
        if (listQuery.size() == 0) {
            //区域编码生成规则
            linkappAreaQuery = new LinkappArea();
            linkappAreaQuery.setParentId(linkappArea.getParentId());
            linkappAreaQuery.setStatus("1");
            List<LinkappArea> list = linkappAreaService.selectLinkappAreaList(linkappAreaQuery);
            linkappAreaQuery = new LinkappArea();
            linkappAreaQuery.setId(linkappArea.getParentId());
            linkappAreaQuery.setLevel(0);
            linkappAreaQuery = linkappAreaService.selectLinkappArea(linkappAreaQuery);
            Integer count = list.size();
            String areaNo = String.format("%3d", count + 1).replace(" ", "0");
            String parentAreaNo = "";
            if (linkappAreaQuery != null && linkappAreaQuery.getAreaNo() != null && linkappAreaQuery.getAreaNo().length() > 0) {
                parentAreaNo = linkappAreaQuery.getAreaNo();
            }
            linkappArea.setAreaNo(parentAreaNo + areaNo);
            linkappAreaService.addLinkappArea(linkappArea);
            return RestBuilders.successBuilder().data(linkappArea).build();
        } else {
            return RestBuilders.failureBuilder().message("区域名称重复").build();
        }


    }

    @ApiOperation("更新区域")
    @PostMapping("/updateLinkappArea")
    @CommonOperateLogAnnotate(module = LogModule.AREA, desc = "更新区域")
    public RestMessage updateLinkappArea(@RequestBody LinkappArea linkappArea) {
        Assert.notNull(linkappArea.getId(), "区域不能为空");
        LinkappArea linkappAreaQuery = new LinkappArea();
        linkappAreaQuery.setAreaName(linkappArea.getAreaName());
        linkappAreaQuery.setParentId(linkappArea.getParentId());
        List<LinkappArea> listQuery = linkappAreaService.selectLinkappAreaList(linkappAreaQuery);
        if (listQuery.size() == 0) {
            return RestBuilders.successBuilder().success(linkappAreaService.updateLinkappArea(linkappArea)).build();
        } else {
            if (linkappArea.getId().equals(listQuery.get(0).getId())) {
                return RestBuilders.successBuilder().success(linkappAreaService.updateLinkappArea(linkappArea)).build();
            } else {
                return RestBuilders.failureBuilder().message("区域名称重复").build();
            }
        }
    }

    @ApiOperation("删除区域")
    @PostMapping("/deleteLinkappArea")
    @CommonOperateLogAnnotate(module = LogModule.AREA, desc = "删除区域")
    public RestMessage deleteLinkappArea(@RequestBody LinkappArea linkappArea) {
        Assert.notNull(linkappArea.getId(), "区域不能为空");
        //空间下是否绑定设备
        Device device = new Device();
        device.setAreaId(linkappArea.getId());
        List<Device> deviceList = deviceService.selectDevices(device);
        if (!deviceList.isEmpty()) {
            return RestBuilders.failureBuilder().message("该区域绑定有设备").build();
        }

        //空间下是否绑定设备
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        QueryWrapper<DeviceRefAreaScope> deviceRefAreaScopeQueryWrapper = new QueryWrapper<>();
        deviceRefAreaScopeQueryWrapper.eq("tenant_id",tenantId);
        deviceRefAreaScopeQueryWrapper.eq("area_id",linkappArea.getId());
        Integer count = deviceRefAreaScopeService.count(deviceRefAreaScopeQueryWrapper);
        if (count != null && count>0) {
            return RestBuilders.failureBuilder().message("该区域绑定有设备").build();
        }

        //资产下是否绑定空间
        QueryWrapper<Asset> wrapper = new QueryWrapper();
        wrapper.eq("asset_area_id", linkappArea.getId());
        List<Asset> assetList = assetService.list(wrapper);
        if (!assetList.isEmpty()) {
            return RestBuilders.failureBuilder().message("该区域绑定有资产").build();
        }

        // 逻辑删除字段设为删除标识
//        linkappArea.setStatus("0");
        return RestBuilders.successBuilder().success(linkappAreaService.removeById(linkappArea)).build();
    }

    @ApiOperation("查询区域列表")
    @PostMapping("/selectLinkappAreaList")
    public RestMessage selectLinkappAreaList(@RequestBody LinkappArea linkappArea) {
        return RestBuilders.successBuilder().data(linkappAreaService.selectLinkappAreaList(linkappArea)).build();
    }

    @ApiOperation("查询区域-单个")
    @PostMapping("/selectLinkappArea")
    public RestMessage selectLinkappArea(@RequestBody LinkappArea linkappArea) {
        return RestBuilders.successBuilder().data(linkappAreaService.selectLinkappArea(linkappArea)).build();
    }

    @ApiOperation("查询区域-树列表")
    @PostMapping("/selectLinkappAreaTreeList")
    public RestMessage selectLinkappAreaTreeList(@RequestBody LinkappArea linkappArea) {
        return RestBuilders.successBuilder().data(linkappAreaService.selectLinkappAreaTreeList(linkappArea)).build();
    }

    @ApiOperation("根据areaPath获取下一级子区域")
    @PostMapping("/selectChildLinkappAreaTreeListByAreaPath")
    public RestMessage selectChildLinkappAreaTreeListByAreaPath(@RequestBody LinkappArea linkappArea) {
        return RestBuilders.successBuilder().data(linkappAreaService.selectChildLinkappAreaTreeListByAreaPath(linkappArea)).build();
    }
    
    @ApiOperation("导入区域")
    @PostMapping("importData")
    @CommonOperateLogAnnotate(module = LogModule.AREA, desc = "更新区域", recordParam = false)
    public RestMessage importData(@RequestParam(value = "file") MultipartFile file,LinkappSpace space) {
        Assert.notNull(file, "文件不能为空");
        Set errors = linkappAreaService.importData(file,space);
        if(errors.isEmpty()) {
        	return RestBuilders.successBuilder().data("导入成功").build();
        }else {
        	String errorMsg = "";
        	for(Object obj : errors) {
            	errorMsg = errorMsg +"第" + obj.toString() + "行  ";
            }
        	errorMsg = errorMsg + "请检查是否为空或重复。";
        	return RestBuilders.successBuilder().data(errorMsg).build();
        }
        
    }
    
    @GetMapping("getImportTemplate")
    @ApiOperation("下载导入模板")
    public void getImportTemplate(HttpServletRequest request, HttpServletResponse response) {
    	linkappAreaService.getImportTemplate(request, response);
    }

    @PostMapping("exportData")
    @ApiOperation("设备导出")
    public void exportData(@RequestBody LinkappArea area, HttpServletRequest request, HttpServletResponse response) {
    	linkappAreaService.exportData(area, request, response);
    }

    /**
     * 绑定租户空间区域
     * @param adp
     * @return
     */
    @ApiOperation("绑定租户空间区域")
    @PostMapping("bindTenantAndAreaPath")
    public RestMessage bindTenantAndAreaPath(@RequestBody DeviceVoExt adp) {
        Assert.notNull(adp.getFunctionIdentifier(), "功能识别码不能为空");
        linkappAreaService.bindTenantAndAreaPath(adp);
        return RestBuilders.successBuilder().message("成功").build();
    }

    /**
     * 获取绑定后的空间区域数据结构--功能识别码过滤
     * @param tfra
     * @return
     */
    @ApiOperation("获取绑定后的空间区域数据结构--功能识别码过滤")
    @PostMapping("getAreaTreeListByFunctionIdentifier")
    public RestMessage getAreaPathListByFunctionIdentifier(@RequestBody TenantFunctionRefArea tfra) {
        Assert.notNull(tfra.getFunctionIdentifier(), "功能识别码不能为空");
        List<SpaceTreeVo> areaPathListByFunctionIdentifier = linkappAreaService.getAreaTreeListByFunctionIdentifier(tfra);
        return RestBuilders.successBuilder().data(areaPathListByFunctionIdentifier).build();
    }

    /**
     * 获取租户下的所有区域
     * @param linkappArea
     * @return
     */
    @ApiOperation("获取租户下的所有区域")
    @PostMapping("/selectAreaListByTenantId")
    public RestMessage selectAreaListByTenantId(@RequestBody LinkappArea linkappArea) {
        return RestBuilders.successBuilder().data(linkappAreaService.selectAreaListByTenantId(linkappArea)).build();
    }

    @ApiOperation("获取空间区域树同时标记最底层区域为true")
    @PostMapping("/selectMostChildAreaList")
    public RestMessage selectMostChildAreaList(@RequestBody LinkappArea linkappArea) {
        return RestBuilders.successBuilder().data(linkappAreaService.selectMostChildAreaList(linkappArea)).build();
    }

    /**
     * 视频监控-树形结构(包含设备)
     */
    @ApiOperation("视频监控-树形结构(包含设备)")
    @PostMapping("/selectAreaTreeListWithDevice")
    public RestMessage selectAreaTreeListWithDevice(@RequestBody LinkappArea linkappArea) {
        List<SpaceTreeVo> list = linkappAreaService.selectAreaTreeListWithDevice(linkappArea);
        return RestBuilders.successBuilder().data(list).build();
    }
}
